package com.DJ;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpStatus;
import org.apache.http.protocol.HTTP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


public class Main {
    private static final Logger log = LoggerFactory.getLogger(UserApplication.class);

    public static void main(String[] args) {
//        // 1.注册账户
//        JSONObject userParam = new JSONObject();
//        userParam.put("user", "user"); // 用户名
//        userParam.put("password", "password"); // 用户口令
//
//        String createUrl = "http://42.202.135.44:8081/fuchain/account/create";
//        String result = doPost(createUrl, userParam.toJSONString(), null);
//        if (result != null) {
//            JSONObject obj = JSONObject.parseObject(result);
//            System.out.println(obj.toJSONString());
//            log.info("注册成功：用户名：{} -- 密码：{}", userParam.get("user"), userParam.get("password"));
//        } else {
//            System.out.println("create account fail!");
//            return;
//        }



        // 2.登陆获取Auth
        JSONObject userParam = new JSONObject();
        userParam.put("user", "user"); // 用户名
        userParam.put("password", "password"); // 用户口令
        String auth = null;
        String loginUrl = "http://42.202.135.44:8081/api/auth/login";
        String loginParam = "user=" + userParam.getString("user") + "&password=" + userParam.getString("password");
        String result1 = doGet(loginUrl, loginParam);
        System.out.println(result1);
        if (result1 != null) {
            JSONObject obj = JSONObject.parseObject(result1);
            String code = obj.getString("code");
            if ("00000".equals(code)) {
                auth = obj.getString("data");
            }
        }
        System.out.println("----------------------2.登陆获取Auth");
        // 3.日志数据上传

        String inputUrl = "";
        JSONObject input = new JSONObject(true);
        JSONObject head = new JSONObject(true);
        JSONObject index = new JSONObject(true);

        index.put("host", "192.168.1.1"); // 日志来源主机ip
        index.put("type", "福州市数据交换平台"); // 日志来源项目/平台的名称
        index.put("timestamp", "2021-05-28 17:13:43"); // 日志时间
        head.put("dataUser", userParam.getString("user")); // 注册用户
        head.put("dataName", "userLog");  // 日志类型：各系统权限管理日志、账户管理日志、登录认证管理日志、系统自身日志、业务访问日志等
        head.put("dataHash", UUID.randomUUID().toString()); //数据唯一ID
        head.put("dataIndex", index);

        input.put("head", head);
        String body = "";
        input.put("body", body);

        //result = doPost(inputUrl,input.toJSONString(),auth);

        // 4.日志文件数据上传
        String fileUrl = "http://42.202.135.44:8081/fuchain/send/file/single";
        String filePath = "D:\\home\\ops\\bot-crm\\log\\info.log";
        uploadFile(fileUrl, auth, input.toJSONString(), filePath);
//        UploadTest01( auth);

//
//        System.out.println(doGet(host1,param1));
        //System.out.println("----------------------3.日志数据上传完毕");
    }

    public static String doGet(String host, String param) {
        StringBuilder json = new StringBuilder();
        BufferedReader in = null;
        try {
            String getUrl = host + "?" + param;
            URL requestUrl = new URL(getUrl);
            //打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection();
            //请求方式
            connection.setRequestMethod("GET");
            //设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            //建立实际的连接
            connection.connect();
            //定义BufferReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine = null;
            while ((inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
        } catch (MalformedURLException e) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("status", "401");
            e.printStackTrace();
            return jsonObject.toJSONString();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("----------------------doGet.建立连接");
        return json.toString();
    }

    public static String doPost(String host, String param, String auth) {
        HttpURLConnection httpURLConnection = null;
        try {
            URL url = new URL(host);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(3000);
            httpURLConnection.setReadTimeout(10000);
            //设置是否向httpURLConnection输出
            httpURLConnection.setDoOutput(true);
            //设置是否从httpURLConnection读入
            httpURLConnection.setDoInput(true);
            //设置是否使用缓存
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestMethod("POST");
            //设置使用标准编码格式编码参数的名-值对
            httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=utf-8");

            if (auth != null) {
                httpURLConnection.addRequestProperty("Authorization", "Bearer " + auth);
            }

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8");
            outputStreamWriter.write(param);
            outputStreamWriter.flush();
            outputStreamWriter.close();

            //得到响应状态码的返回值 responseCode
            int responseCode = httpURLConnection.getResponseCode();

            if (HttpStatus.SC_OK == responseCode) {
                StringBuffer stringBuffer = new StringBuffer();

                InputStream inputStream = httpURLConnection.getInputStream();
                String strLine = "";
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

                while (null != (strLine = bufferedReader.readLine())) {
                    stringBuffer.append(strLine);
                }
                bufferedReader.close();

                System.out.println("Post请求成功，响应状态码 :" + responseCode + " 返回数据 ：" + stringBuffer.toString());
                System.out.println("----------------------doPost");
                return stringBuffer.toString();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    public static void uploadFile(String host, String auth, String input, String fileName) {

        HttpURLConnection httpURLConnection = null;

        try {
            // 换行符
            final String newLine = "\r\n";
            final String boundaryPrefix = "--";
            // 定义数据分隔线
            String BOUNDARY = "========7d4a6d158c9";
            // 服务器的域名
            URL url = new URL(host);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            // 设置为POST情
            httpURLConnection.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);

            // 设置请求头参数
            httpURLConnection.setRequestProperty("connection", "Keep-Alive");
            httpURLConnection.setRequestProperty("Charsert", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            if (auth != null) {
                httpURLConnection.addRequestProperty("Authorization", "Bearer " + auth);
            }
            OutputStream out = httpURLConnection.getOutputStream();
            // 上传文件
            File file = new File(fileName);
            StringBuilder sb = new StringBuilder();
            sb.append(boundaryPrefix);
            sb.append(BOUNDARY);
            sb.append(newLine);
            // 文件参数,photo参数名可以随意修改

            String content = "--" + BOUNDARY + "\r\n";
            content += "Content-Disposition: form-data; name=\"input\"" + "\r\n\r\n";
            content += input;
            content += "\r\n--" + BOUNDARY + "\r\n";
            content += "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n";
            content += "Connection: Keep-Alive\r\n";
            content += "Content-Type: multipart/form-data\r\n\r\n";

            sb.append(content);
//            sb.append("Content-Disposition: form-data;name=\""+input+"\";filename=\""+ fileName + "\"" + newLine);
            //sb.append("Content-Type:application/octet-stream");
            // 参数头设置完以后需要两个换行，然后才是参数内容
            sb.append(newLine);
            sb.append(newLine);

            System.out.println(sb.toString());
            // 将参数头的数据写入到输出流中
            out.write(sb.toString().getBytes());
            // 数据输入流,用于读取文件数据
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            byte[] bufferOut = new byte[1024];
            int bytes = 0;
            // 每次读1KB数据,并且将文件数据写入到输出流中
            while ((bytes = in.read(bufferOut)) != -1) {
                System.out.println(bytes);
                out.write(bufferOut, 0, bytes);
            }
            // 最后添加换行
            out.write(newLine.getBytes());
            in.close();
            // 定义最后数据分隔线，即--加上BOUNDARY再加上--。
            byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes();
            // 写上结尾标识
            out.write(end_data);
            out.flush();
            out.close();

            //定义BufferedReader输入流来读取URL的响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                System.out.println("上传文件返回："+line);
            }
            //System.out.println("----------------------Upload_File.开始上传");
        } catch (Exception e) {
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
        }
    }



    public void doHttpPostTest(String auth) throws UnsupportedEncodingException {
        // -------------------------------> 获取Rest客户端实例
        RestTemplate restTemplate = new RestTemplate();

        // -------------------------------> (选择性设置)请求头信息
        // HttpHeaders实现了MultiValueMap接口
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置contentType
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 给请求header中添加一些数据
        httpHeaders.add("Authorization", "Bearer " + auth);

        // ------------------------------->将请求头、请求体数据，放入HttpEntity中
        // 请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
        // 这里手写了一个json串作为请求体 数据 (实际开发时,可使用fastjson、gson等工具将数据转化为json串)
        // String httpBody = "{\"motto\":\"唉呀妈呀！脑瓜疼！\"}";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", "是一个中文名");
        paramMap.put("englishName", "merry");
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(paramMap, httpHeaders);

        // -------------------------------> URI
        StringBuffer paramsURL = new StringBuffer("http://127.0.0.1:8080/http/doHttpTest");
        // 字符数据最好encoding一下;这样一来，某些特殊字符才能传过去(如:flag的参数值就是“&”,不encoding的话,传不过去)
        paramsURL.append("?flag=" + URLEncoder.encode("&&", "utf-8"));
        URI uri = URI.create(paramsURL.toString());

        //  -------------------------------> 执行请求并返回结果
        // 此处的泛型  对应 响应体数据   类型;即:这里指定响应体的数据装配为String
        // 访问方式一:
//        ResponseEntity<String> response =
//                restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);
        // 访问方式二:
        ResponseEntity<String> response = restTemplate.postForEntity(uri, httpEntity, String.class);

        // -------------------------------> 响应信息
        //响应码,如:401、302、404、500、200等
        System.err.println(response.getStatusCodeValue());
        // 响应头
        System.err.println(JSON.toJSON(response.getHeaders()));
        // 响应体
        if (response.hasBody()) {
            System.err.println(response.getBody());
        }
    }

    public static void UploadTest01(String auth) {
        RestTemplate restTemplate = new RestTemplate();
        //文件地址和请求url
        String filePath = "D:\\develop\\code\\DJ\\DJ_admin\\log\\";
        String fileName = "imcoding.log";
        String url = "http://42.202.135.44:8081/fuchain/send/file/single";

        //构造请求头
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);

       // httpURLConnection.addRequestProperty("Authorization", "Bearer " + auth);
        headers.setBearerAuth(auth);
        System.out.println(headers.toString());

        //FileSystemResource将文件变成流以发送
        FileSystemResource fileSystemResource = new FileSystemResource(filePath+"/"+fileName);

        //构造请求体，使用LinkedMultiValueMap
        MultiValueMap<String, Object> resultMap = new LinkedMultiValueMap<>();
        resultMap.add("file", fileSystemResource);
        resultMap.add("filename", fileName);

        //HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(resultMap, headers);

        //postForObject发送请求体
        String result = restTemplate.postForObject(url, httpEntity, String.class);
        System.out.println("result = " + result);
    }


//    public static MultipartFile fileToMultipartFile(File file,String filePath) throws Exception {
//        String fileName = file.getName();
//        String contentType = Files.probeContentType(Paths.get(filePath));
//        MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, contentType, new FileInputStream(file));
//        return multipartFile;
//    }


}